﻿//     Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.ComponentModel.DataAnnotations;
using System.Reflection;

namespace Gateway.Console.Models.Validation
{
    class ConditionalRequiredAttribute : RequiredAttribute
    {
        delegate bool StaticInvocation(object model);
        StaticInvocation _validationMethod;

        /// <summary>
        /// The name of the static method on the model class that will validate if the value is NOT required
        /// </summary>
        public string ValidationMethod { get; set; }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (!String.IsNullOrWhiteSpace(this.ValidationMethod))
            {
                if (this._validationMethod == null)
                {
                    MethodInfo method = null;
                    for (Type objectType = validationContext.ObjectType; method == null && objectType != null; objectType = objectType.BaseType)
                    {
                        method = objectType.GetMethod(this.ValidationMethod, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
                    }
                    if (method != null)
                    {
                        this._validationMethod = (StaticInvocation)method.CreateDelegate(typeof(StaticInvocation));
                    }
                }
                if (this._validationMethod != null)
                {
                    if (this._validationMethod(validationContext.ObjectInstance))
                    {
                        return ValidationResult.Success;
                    }
                }
            }
            return base.IsValid(value, validationContext);
        }
    }
}